library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity OPADD is
	Port ( a : in STD_LOGIC_VECTOR (15 downto 0);
		astr : in STD_LOGIC;
		b : in STD_LOGIC_VECTOR (15 downto 0);
		bstr : in STD_LOGIC;
		zack : in STD_LOGIC;
		clkin: in STD_LOGIC;
		aack : out STD_LOGIC;
		back : out STD_LOGIC;
		z : out STD_LOGIC_VECTOR (15 downto 0);
		zstr : out STD_LOGIC);
end OPADD;

architecture Behavioral of OPADD is
	type estados is(soma, envio);
	begin
		dados: process(clkin, astr, bstr, zack)
		variable estado: estados := soma;
		variable reca: STD_LOGIC := '0';
		variable recb: STD_LOGIC := '0';
		variable ad: STD_LOGIC_VECTOR(15 downto 0);
		variable bd: STD_LOGIC_VECTOR(15 downto 0);
		variable zd: STD_LOGIC_VECTOR(15 downto 0);
	begin
		if clkin'event and clkin = '1' then
			z <= "ZZZZZZZZZZZZZZZZ";
			zstr <= '0';
			aack <= '0';
			back <= '0';
			case estado is
				when soma =>
					if astr = '1' then
						ad := a;
						aack <= '1';
						reca := '1';
					end if;
					if bstr = '1' then
						bd := b;
						back <= '1';
						recb := '1';
					end if;
					if reca = '1' and recb = '1' then
						zd := ad + bd;
						reca := '0';
						recb := '0';
						estado := envio;
					end if;
				when envio =>
					if zack = '1' then
						estado := soma;
					else
						z <= zd;
						zstr <= '1';
					end if;
			end case;
		end if;
	end process dados;
end Behavioral;